﻿using System;
using MEF_Test.Subtitles;

namespace MEF_Test.VideoRenderer.LocalVideoRenderer
{
    using System.ComponentModel.Composition;

    using Contracts;

    using Microsoft.Practices.Prism.Regions;

    /// <summary>
    /// A video renderer to render video on the local computer.
    /// </summary>
    /// <remarks>This implementation of video renderer is tightly coupled with the <see cref="MEF_Test.Subtitles"/> namespace, therefore, the related dll must be added as a reference.</remarks>
    
    [Export(typeof(IVideoRendererController))]
    public class LocalVideoRendererController : IVideoRendererController
    {
        /// <summary>
        /// The constant string to provide to the settings manager to identify the Target Monitor Number.
        /// </summary>
        private const string TargetMonitorSettingsString = "IVideoRenderer.TargetMonitor";

        /// <summary>
        /// The settings manager used to store and retrieve configurable values.
        /// </summary>
        private readonly ISettingsManager _settingsManager;

        private readonly IRegionManager _regionManager;
        private readonly ISubtitleSelectionViewFactory _subtitleSelectionViewFactory;
        private readonly ISubtitlesSelectionPageViewModelFactory _subtitlesSelectionPageViewModelFactory;

        private readonly IVideoRendererViewModelFactory _videoRendererViewModelFactory;

        private readonly IVideoRendererViewFactory _videoRendererViewFactory;

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="LocalVideoRendererController"/> class.
        /// </summary>
        /// <param name="settingsManager">The settings manager.</param>
        /// <param name="regionManager">The region manager.</param>
        /// <param name="subtitleSelectionViewFactory">The factory to use to create a view for the subtitle selection.</param>
        /// <param name="subtitlesSelectionPageViewModelFactory">The factory to use to create the view model behind a subtitles selection page.</param>
        /// <param name="videoRendererViewModelFactory">The video renderer view model factory.</param>
        /// <param name="videoRendererViewFactory">The video renderer view factory.</param>
        [ImportingConstructor]
        public LocalVideoRendererController(ISettingsManager settingsManager, IRegionManager regionManager, ISubtitleSelectionViewFactory subtitleSelectionViewFactory, ISubtitlesSelectionPageViewModelFactory subtitlesSelectionPageViewModelFactory, IVideoRendererViewModelFactory videoRendererViewModelFactory, IVideoRendererViewFactory videoRendererViewFactory)
        {
            _settingsManager = settingsManager;
            this._videoRendererViewFactory = videoRendererViewFactory;
            this._videoRendererViewModelFactory = videoRendererViewModelFactory;
            _subtitlesSelectionPageViewModelFactory = subtitlesSelectionPageViewModelFactory;
            _regionManager = regionManager;
            _subtitleSelectionViewFactory = subtitleSelectionViewFactory;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the target monitor.
        /// </summary>
        /// <value>The target monitor.</value>
        public int TargetMonitor
        {
            get
            {
                // TODO : use config file to define the value of the TargetMonitor.
                return _settingsManager.GetSetting<int>(TargetMonitorSettingsString);
            }

            set
            {
                _settingsManager.SetSetting(TargetMonitorSettingsString, 10);
            }
        }
      

        #endregion

        #region Implemented Interfaces

        #region IVideoRenderer

        /// <summary>
        /// Opens the video.
        /// </summary>
        /// <param name="browserNodeViewModel">The browser node view model.</param>
        public void OpenVideo(IBrowserNodeViewModel browserNodeViewModel)
        {
            // TODO : Remove magic strings
            const string subtitlesSelectionViewName = "SubtitlesSelectionView";

            // TODO : Remove magic strings
            var localControlsRegion = _regionManager.Regions["LocalControls"];

            var subtitlesSelectionView = localControlsRegion.GetView(subtitlesSelectionViewName) as ISubtitlesSelectionView;

            ISubtitlesSelectionPageViewModel viewModel = _subtitlesSelectionPageViewModelFactory.Create(browserNodeViewModel, localControlsRegion, browserNodeViewModel.FileHandler);
            
            // Once a subtitles is selected, load it and play the video with it.
            viewModel.SubtitleSelectionValidated += OnSubtitleSelectionValidated;

            if (subtitlesSelectionView == null)
            {
                subtitlesSelectionView = _subtitleSelectionViewFactory.Create(viewModel);
                localControlsRegion.Add(subtitlesSelectionView, subtitlesSelectionViewName);
            }
            // FIXME : We don't need a subtitlesSelectionPageViewModel : we need an "OpenVideoMediaPageViewModel" or something like that. Subtitles-related viewmoels shouldn't have any info about the node !

            //// TODO : Deal with subtitle Selection that get displayed a 2nd time ( i.e. the view already exists : keep the bindings working : try not to discard the whole view, only reloading/requerying the values. )
            viewModel.FetchSubtitles();

            ////subtitlesSelectionView.DataContext = dataContext;
            localControlsRegion.Activate(subtitlesSelectionView);

            //// FIXME : Use dependency injection and/or factory to instanciate the LocalVideoRendererWindow ( the view for the IVideoRenderer )            
            //var viewName = typeof(LocalVideoRendererWindow).FullName;

            //var regionName = "DedicatedMonitorLocalRenderer";    
  
            //var rendererRegion = _regionManager.Regions[regionName];
            //var view = rendererRegion.GetView(viewName);
            //if (view == null)
            //{
            //    var videoRendererWindowViewModel = new VideoRendererWindowViewModel(_regionManager)
            //        {
            //            FileHandler = browserNodeViewModel.FileHandler                   
            //        };
            //    view = new LocalVideoRendererWindow { DataContext = videoRendererWindowViewModel };
            //    rendererRegion.Add(view, viewName);
            //}

            //_regionManager.Regions[regionName].Activate(view);

            //var localControlsRegion = _regionManager.Regions["LocalControls"];
            //var controlsView = localControlsRegion.GetView("LocalControlsView");
            //localControlsRegion.Deactivate(controlsView);
        }

        private void OnSubtitleSelectionValidated(object sender, SubtitleSelectionValidatedArgs args)
        {
            // Open the actual video player, injecting the selected subtitles.
            // TODO : Remove magic strings
            var regionName = "VideoPlayerRegion";

            var rendererRegion = _regionManager.Regions[regionName];
            
            // TODO : Remove magic strings
            string viewName = "VideoPlayerView";

            var view = rendererRegion.GetView(viewName);
            if (view == null)
            {
                var videoRendererWindowViewModel = _videoRendererViewModelFactory.Create(_regionManager, args.BrowserNodeViewModel, args.SelectedSubtitle);
                view = _videoRendererViewFactory.Create(videoRendererWindowViewModel);
                rendererRegion.Add(view, viewName);
            }

            // Deactivate the controls
            // TODO : Remove magic strings
            var localControlsRegion = _regionManager.Regions["LocalControls"];

            // TODO : Remove magic strings
            const string subtitlesSelectionViewName = "SubtitlesSelectionView";
            var subtitlesSelectionView = localControlsRegion.GetView(subtitlesSelectionViewName) as ISubtitlesSelectionView;
            if (subtitlesSelectionView != null)
            {
                localControlsRegion.Deactivate(subtitlesSelectionView);
            }
        }

        #endregion

        #endregion
    }

}
